/**
 * $version:  0.1 
 * $Date: 2012-05-08
 *
 * Copyright (C) 2010-2012 Jawa Software. All rights reserved.
 *
 */
package org.jawa.learning.webapp.servlet;

import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.jawa.core.util.JawaConstants;
import org.jawa.learning.model.Menu;
import org.jawa.learning.model.Role;
import org.jawa.learning.model.User;
import org.jawa.learning.service.MenuManager;
import org.jawa.learning.service.UserManager;
import org.jawa.learning.webapp.taglib.MenuComponent;
import org.jawa.learning.webapp.taglib.MenuRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * 管理台用户登录控制
 */
public final class AdminAuthServlet extends HttpServlet {

	private static final long serialVersionUID = -533293612573583289L;

	private static final Logger Log = LoggerFactory.getLogger(AdminAuthServlet.class);

	// 登录验证页面
	private static String FORM_LOGIN_PAGE = null;
	// 登录出错页面
	private static String FORM_ERROR_PAGE = null;
	// 登录成功页面
	private static String FORM_TARGET_PAGE = null;

	/**
	 * 获取与初始化系统登录的参数.
	 * 
	 * @throws ServletException
	 *             if the init parameters are invalid or any other problems
	 *             occur during initialisation
	 */
	public void init() throws ServletException {
		FORM_LOGIN_PAGE = getInitParameter("form-login-page");
		FORM_ERROR_PAGE = getInitParameter("form-error-page");
		FORM_TARGET_PAGE = getInitParameter("form-target-page");

		Log.debug("登录验证页面: " + FORM_LOGIN_PAGE);
		Log.debug("登录出错页面: " + FORM_ERROR_PAGE);
		Log.debug("登录成功页面: " + FORM_TARGET_PAGE);
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		execute(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		execute(request, response);
	}

	/**
	 * 处理http 请求.
	 * 
	 * @param request
	 *            The HTTP request we are processing
	 * @param response
	 *            The HTTP response we are creating
	 * 
	 * @exception IOException
	 *                if an input/output error occurs
	 * @exception ServletException
	 *                if a servlet exception occurs
	 */
	public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		HttpSession session = request.getSession(true);
		ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());

		String username = StringUtils.trimToEmpty(request.getParameter("j_username"));
		String password = StringUtils.trimToEmpty(request.getParameter("j_password"));
		boolean loginSuccess = false;
		UserManager userManager = (UserManager) ctx.getBean("userManager");
		User user = null;
		try {
			Log.debug("开始验证用户: '" + username + "'");

			user = userManager.getUserByUsername(username);
			if (null != user && StringUtils.equals("2", user.getUserType())
					&& StringUtils.equalsIgnoreCase(user.getPassword(), DigestUtils.md5Hex(password))) {
				loginSuccess = true;
			} else {
				// 用户不存在或密码不正确
				loginSuccess = false;
				Log.debug("登录用户不存在或密码错误! username:" + username);
			}
		} catch (Exception e) {
			Log.debug("用户登录时发生异常: '" + username + "'", e);
			loginSuccess = false;
		}

		if (loginSuccess) {
			// 初始化用户参数
			Log.debug("验证用户'" + username + "'成功,开始初始化用户参数信息!");
			initUserParameters(request, response, user);
			Log.debug("初始化用户'" + username + "'完成,转入成功页面!");

			// 转向上次访问的页面
			String from = request.getParameter("from");
			if (StringUtils.isNotEmpty(from)) {
				response.sendRedirect(from);
			} else {
				response.sendRedirect(request.getContextPath() + response.encodeRedirectURL(FORM_TARGET_PAGE));
			}

		} else {
			Log.debug("验证用户'" + username + "'失败,转入错误页面! ");
			
			String from = request.getParameter("from");
			if (StringUtils.isNotEmpty(from)) {
				if(FORM_ERROR_PAGE.indexOf("?")>0){
					FORM_ERROR_PAGE = FORM_ERROR_PAGE + "&from="+from;
				}else{
					FORM_ERROR_PAGE = FORM_ERROR_PAGE + "?from="+from;
				}
			}
			
			response.sendRedirect(request.getContextPath() + response.encodeRedirectURL(FORM_ERROR_PAGE));
			
		}
	}

	/**
	 * 初始化用户信息。
	 * 
	 * @param request
	 * @param response
	 */
	private void initUserParameters(HttpServletRequest request, HttpServletResponse response, User user) {
		HttpSession session = request.getSession(true);
		ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());
		MenuManager menuManager = (MenuManager) ctx.getBean("menuManager");

		// 用户的菜单信息
		List<Menu> userMenus = new ArrayList<Menu>();

		Set<Role> userRoles = user.getRoles();
		for (Iterator iterator = userRoles.iterator(); iterator.hasNext();) {
			Role role = (Role) iterator.next();
			List<Menu> roleMenus = menuManager.getMenusByRole(role.getId());
			userMenus.addAll(roleMenus);
		}

		MenuRepository repository = new MenuRepository();
		for (Iterator<Menu> iterator = userMenus.iterator(); iterator.hasNext();) {
			Menu menu = (Menu) iterator.next();
			MenuComponent mc = new MenuComponent();
			mc.setId(menu.getId());
			mc.setParentId(menu.getParentId());
			Long menuParent = menu.getParentId();
			if (menuParent != null) {
				MenuComponent parentMenu = repository.getMenu(menuParent);
				if (parentMenu == null) {
					parentMenu = new MenuComponent();
					parentMenu.setId(menuParent);
					repository.addMenu(parentMenu);
				}
				mc.setParent(parentMenu);
			}
			mc.setId(menu.getId());
			mc.setMenuName(menu.getMenuName());
			if (StringUtils.isNotEmpty(menu.getMenuUrl())) {
				mc.setMenuUrl(request.getContextPath() + menu.getMenuUrl());
			}
			repository.addMenu(mc);
		}

		// 初始化用户的菜单信息并放入session中
		session.setAttribute(JawaConstants.MENU_REPOSITORY_KEY, repository);

		// 登录成功，将用户信息放入 session 中
		session.setAttribute(JawaConstants.ADMIN_USER_KEY, user);
	}

}
